package cn.iocoder.yudao.module.member.user.service;

import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.common.exception.Assertions;
import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils;
import cn.iocoder.yudao.framework.util.TransactionUtils;
import cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils;
import cn.iocoder.yudao.module.api.infrastructure.sms.SmsCodeApi;
import cn.iocoder.yudao.module.api.member.user.enums.MemberSmsSceneEnum;
import cn.iocoder.yudao.module.member.user.convert.AuthConvertV2;
import cn.iocoder.yudao.module.member.user.dal.dataobject.MemberUserDO;
import cn.iocoder.yudao.module.member.user.mq.MemberUserProducer;
import cn.iocoder.yudao.module.member.user.vo.AppAuthLoginReqVO;
import cn.iocoder.yudao.module.member.user.vo.AppAuthLoginRespVO;
import cn.iocoder.yudao.module.member.user.vo.AppAuthRegisterReqVO;
import cn.iocoder.yudao.module.member.user.vo.AppAuthRegisterReqVOV2;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * <pre>
 * OOoO0OOoO0OOOooo0oOOOO0OOOOO0oooOO0ooOOO0Ooooo0OOOOo0ooooO0OOooo0Ooooo0OOOOO
 *  用户注册 CrudService 实现
 * OOoO0OOoO0OOOooo0oOOOO0OOOOO0oooOO0ooOOO0Ooooo0OOOOo0ooooO0OOooo0Ooooo0OOOOO
 * </pre>
 *
 * @author 山野羡民（1032694760@qq.com）
 * @since 2024/11/29
 */
@Service
@Slf4j
public class MemberRegisterServiceImpl implements MemberRegisterService {
    @Resource
    private MemberUserService memberUserService;
    @Resource
    private MemberAuthService memberAuthService;

    @Resource
    private MemberUserProducer memberUserProducer;

    @Resource
    private SmsCodeApi smsCodeApi;

    @Transactional(rollbackFor = Exception.class)
    @Deprecated
    @Override
    public AppAuthLoginRespVO register(AppAuthRegisterReqVO reqVO) {
        Integer terminal = WebFrameworkUtils.getTerminal();
        String ip = ServletUtils.getClientIP();
        // 用户已经存在
        MemberUserDO user = memberUserService.getUserByUsername(reqVO.getUsername());
        Assertions.isTrue(user == null, "用户名已被占用");
        // 用户不存在，则进行创建
        MemberUserDO aDo = memberUserService.createUser(reqVO.getUsername(), reqVO.getPassword(), null, null, ip, terminal, false);
        Assertions.isTrue(aDo != null, "注册失败");
        log.info("[register]新用户({})密码注册成功：userId({})", reqVO.getUsername(), aDo.getId());
        bindRelation(aDo.getId(), reqVO.getInviteCode());
        return memberAuthService.login(new AppAuthLoginReqVO()
                .setMobile(reqVO.getUsername())
                .setPassword(reqVO.getPassword()));
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public MemberUserDO register(AppAuthRegisterReqVOV2 reqVO) {
        String ip = ServletUtils.getClientIP();
        // 使用验证码
        smsCodeApi.useSmsCode(AuthConvertV2.INSTANCE.convert(reqVO, MemberSmsSceneEnum.MEMBER_REGISTER.getValue(), ip));
        String mobile = reqVO.getMobile();
        Integer terminal = WebFrameworkUtils.getTerminal();
        // 用户已经存在
        MemberUserDO user = memberUserService.getUserByMobile(mobile);
        Assertions.isTrue(user == null, "手机号已被占用");
        // 用户不存在，则进行创建
        MemberUserDO aDo = memberUserService.createUser(mobile, reqVO.getPassword(), null, null, ip, terminal, false);
        Assertions.isTrue(aDo != null, "注册失败");
        log.info("[register]新用户({})短信验证码注册成功：userId({})", reqVO.getMobile(), aDo.getId());
        bindRelation(aDo.getId(), reqVO.getInviteCode());
        return aDo;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean bindRelation(Long userId, String inviteCode) {
        if (userId == null || userId <= 0L || StrUtil.isBlank(inviteCode)) {
            log.info("[register]新用户注册未绑定推广关系：userId({}), inviteCode({}), 原因：参数为空", userId, inviteCode);
            return false;
        }
        Long inviteUserId = memberUserService.getUserIdByInviteCode(inviteCode);
        if (inviteUserId == null || inviteUserId <= 0) {
            log.warn("[register]新用户注册未绑定推广关系：userId({}), inviteCode({}), 原因：邀请码不存在", userId, inviteCode);
            return false;
        }
        return bindRelation(userId, inviteUserId);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean bindRelation(Long userId, Long inviteUserId) {
        if (userId == null || userId <= 0L || inviteUserId == null || inviteUserId <= 0L) {
            log.info("[register]新用户注册未绑定推广关系：userId({}), inviteUserId({}), 原因：参数为空", userId, inviteUserId);
            return false;
        }
        if (userId.equals(inviteUserId)) {
            log.warn("[register]新用户注册未绑定推广关系：userId({}), inviteUserId({}), 原因：不能自己绑定自己", userId, inviteUserId);
            return false;
        }
        MemberUserDO inviteUser = memberUserService.getUser(inviteUserId);
        if (inviteUser == null) {
            log.warn("[register]新用户注册未绑定推广关系：userId({}), inviteUserId({}), 原因：推荐码所属用户不存在", userId, inviteUserId);
            return false;
        }
        if (userId.equals(inviteUser.getPid())) {
            log.warn("[register]新用户注册未绑定推广关系：userId({}), inviteUserId({}), 原因：不能互推", userId, inviteUserId);
            return false;
        }
        boolean bindSuccess = memberUserService.bindInviteUser(userId, inviteUserId);
        log.info("[register]新用户注册绑定推广关系：userId({}), inviteUserId({}), bindSuccess({})", userId, inviteUserId, bindSuccess);
        if (bindSuccess) {
            TransactionUtils.afterCommit(() -> {
                memberUserProducer.sendUserInviteMessage(userId, inviteUserId);
                return null;
            });
        }
        return bindSuccess;
    }

}
